#!/usr/bin/perl

use strict;
use warnings;
use warnings::register;
use integer;
use POSIX qw(strftime);
use Time::Local;

$ENV{'PATH'} = "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin";

# WorkRaveStats 4
# D 16 5 104 14 51 17 5 104 3 59
# B 0 7 9 8 40 0 0 9 386 
# B 1 7 4 1 0 1 3 4 362 
# B 2 7 0 0 0 0 0 0 0 
# m 6 6049 234742 113560 266 417 16617 
# D 17 5 104 16 49 18 5 104 3 59
# B 0 7 1 0 3 0 0 1 526 
# B 1 7 3 0 0 0 2 2 1768 
# B 2 7 0 0 0 0 0 0 872 
# m 6 15272 39275 11937 36 30 1899 
#
# D(ate):	[ tm_mday tm_mon tm_year tm_hour tm_min ] {2}
#
# B(reak):	<t> <nn> <x0> <x1> <x2> <x3> <x4> <x5> <x6>
#
#	<t> = break type
# 		0 = microbreak
#		1 = rest break
#		2 = daily limit
#
#	<nn> STATS_BREAKVALUE_SIZEOF - number of following numbers
#
#	<x0> STATS_BREAKVALUE_PROMPTED - break prompts<x6> + repeated prompts
#	<x1> STATS_BREAKVALUE_TAKEN - prompted breaks taken
#	<x2> STATS_BREAKVALUE_NATURAL_TAKEN - natural breaks taken
#	<x3> STATS_BREAKVALUE_SKIPPED - breaks skipped
#	<x4> STATS_BREAKVALUE_POSTPONED - breaks postponed
#	<x5> STATS_BREAKVALUE_UNIQUE_BREAKS - break prompts
#	<x6> STATS_BREAKVALUE_TOTAL_OVERDUE - overdue time (seconds)
#
# m(isc):	<nn> <x0> <x1> <x2> <x3> <x4> <x5>
#
# 	<nn> STATS_VALUE_SIZEOF
#	<x0> STATS_VALUE_TOTAL_ACTIVE_TIME (seconds)
#	<x1> STATS_VALUE_TOTAL_MOUSE_MOVEMENT
#	<x2> STATS_VALUE_TOTAL_CLICK_MOVEMENT
#	<x3> STATS_VALUE_TOTAL_MOVEMENT_TIME (seconds)
#	<x4> STATS_VALUE_TOTAL_CLICKS
#	<x5> STATS_VALUE_TOTAL_KEYSTROKES
sub dumpdata($$$$$)
{
	my ($tmdate, $break, $misc, $breakstats, $miscstats) = @_;

	warnings::warn "No timestamp at line $.\n" if !defined($tmdate);
	warnings::warn "No breaks at line $.\n" if !defined($break);
	foreach my $breaktype (0..2) {
		if (!defined($break->{$breaktype})) {
			warnings::warn "No breaktype #$breaktype at line $.\n";
			return;
		}
	}
	warnings::warn "No misc at line $.\n" if !defined($misc);
	if (!defined($tmdate) || !defined($break) || !defined($misc)) {
		return;
	}

	my $ts = strftime("%Y%m%d%H%M", gmtime(timegm(0,
		@$tmdate{qw(min hour mday mon year)})));
	my @breakstrs;
	foreach my $breaktype (0..2) {
		$breakstrs[$breaktype] = join(" ",
			@{$break->{$breaktype}}{@$breakstats});
	}
	my $breakstr = join(" ", @breakstrs);
	my $miscstr = join(" ", @$misc{@$miscstats});

	print "$ts $breakstr $miscstr\n";
}

#
# Initialize RRD
#

my @breakstats = qw(prompted taken natural skipped
	postponed unique overduetime);
my @miscstats = qw(activetime mousemovement clickmovement movementtime clicks
	keystrokes);

my $step = 24 * 3600;	# 24-hr steps
my $heartbeat = 4 * $step;

my (@DS);
my @breaktypes = qw(micro rest daily);
foreach my $breaktype (@breaktypes) {
	foreach my $breakstat (@breakstats) {
		my $key = "$breaktype$breakstat";
		push @DS, "DS:$key:GAUGE:$heartbeat:0:U";
	}
}
foreach my $miscstat (@miscstats) {
	push @DS, "DS:$miscstat:GAUGE:$heartbeat:0:U";
}
umask(022);

#
# Populate data
#
my $source = ( $^O eq 'MSWin32' ) ? "$ENV{APPDATA}\\Workrave\\historystats" : "$ENV{HOME}/.workrave/historystats";
my $first = 1;
my ($tmdate, $break, $misc) = (undef, undef, undef);
open(SOURCE, $source) or die "open $source: $!\n";
while (<SOURCE>) {
	chomp;
	s/^\0*//; # remove corrupted data
	if (/^WorkRaveStats 4$/) {
		# Ignore header
		next;
	} elsif (m/^D\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)
			\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*$/x) {
		if ($first) {
			$first = 0;
		} else {
			dumpdata($tmdate, $break, $misc,
				[@breakstats], [@miscstats]);
		}
		$tmdate = {
			mday => $1,
			mon => $2,
			year => $3,
			hour => $4,
			min => $5,
		};
=cut
		$tmdate = {
			mday => $6,
			mon => $7,
			year => $8,
			hour => $9,
			min => $10,
		};
=cut
		$break = $misc = undef;
	} elsif (m/^B\s+([012])\s+7
			\s+(\d+)\s+(\d+)\s+(\d+)
			\s+(\d+)\s+(\d+)\s+(\d+)
			\s+(\d+)\s*$/x) {
		my $type = $1;
		$break->{$type} = {
			prompted => $2,
			taken => $3,
			natural => $4,
			skipped => $5,
			postponed => $6,
			unique => $7,
			overduetime => $8,
		};
	} elsif (m/^m\s+6\s+(\d+)\s+(\d+)\s+(\d+)
			\s+([-0-9]+)\s+(\d+)\s+(\d+)\s*$/x) {
		$misc = {
			activetime => $1,
			mousemovement => $2,
			clickmovement => $3,
			movementtime => $4,
			clicks => $5,
			keystrokes => $6,
		};
	} else {
		die "Unrecognized line (line $.): [$_]\n";
	}
}
close(SOURCE) or die "close $source: $!\n";
dumpdata($tmdate, $break, $misc, [@breakstats], [@miscstats]);
